(function($){
	var touch = {}, touchTimeout;

	function parentIfText(node){
		return 'tagName' in node ? node : node.parentNode;
	}

	function swipeDirection(x1, x2, y1, y2){
		var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2);
		if (xDelta >= yDelta) {
		return (x1 - x2 > 0 ? 'Left' : 'Right');
		} else {
		return (y1 - y2 > 0 ? 'Up' : 'Down');
		}
	}

	$(document).ready(function(){
		$(document.body).bind('touchstart', function(e){
			var now = Date.now(), delta = now - (touch.last || now);
			touch.target = parentIfText(e.touches[0].target);
			touchTimeout && clearTimeout(touchTimeout);
			touch.x1 = e.touches[0].pageX;
			touch.y1 = e.touches[0].pageY;
			if (delta > 0 && delta <= 250) touch.isDoubleTap = true;
			touch.last = now;
		}).bind('touchmove', function(e){
			touch.x2 = e.touches[0].pageX;
			touch.y2 = e.touches[0].pageY;
		}).bind('touchend', function(e){
			if (touch.isDoubleTap) {
				$(touch.target).trigger('doubleTap');
				touch = {};
			} else if (touch.x2 > 0 || touch.y2 > 0) {
				(Math.abs(touch.x1 - touch.x2) > 30 || Math.abs(touch.y1 - touch.y2) > 30)  &&
				$(touch.target).trigger('swipe') &&
				$(touch.target).trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
				touch.x1 = touch.x2 = touch.y1 = touch.y2 = touch.last = 0;
			} else if ('last' in touch) {
				touchTimeout = setTimeout(function(){
					touchTimeout = null;
					$(touch.target).trigger('tap')
					touch = {};
				}, 250);
			}
		}).bind('touchcancel', function(){ touch = {} });
	});

	['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap'].forEach(function(m){
		$.fn[m] = function(callback){ return this.bind(m, callback) }
	});
})(tKit);
